/*
 Contém as funções correspondentes aos opcodes,
 bem como a função execute(), responsável por chamar as funções dos opcodes.
 */

#include <math.h>
#include <string.h>
#include "run.h"
#include "classfile.h"
#include "bytecode.h"
#include "frame.h"
#include "stack.h"

extern stack *framestack;
extern class_list *methodarea;
extern class_file *mainclass;

/* excecoes */
void exception(int exc);

/*Sem ação*/
u1 nop(u1* code) {
	return 0;
}
/*coloca referencia null na pilha de operandos*/
u1 aconst_null(u1* code) {
	push_op(0);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

/*coloca a constante -1, do tipo inteiro, na pilha de operandos*/
u1 iconst_m1(u1* code) {
	s4 param = -1;
	push_op((s4) param);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
/*coloca a constante 0, do tipo inteiro, na pilha de operandos*/
u1 iconst_0(u1* code) {
	u4 param = 0;
	push_op((u4) param);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
/*coloca a constante 1, do tipo inteiro, na pilha de operandos*/
u1 iconst_1(u1* code) {
	u4 param = 1;
	push_op((u4) param);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
/*coloca a constante 2, do tipo inteiro, na pilha de operandos*/
u1 iconst_2(u1* code) {
	u4 param = 2;
	push_op((u4) param);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
/*coloca a constante 3, do tipo inteiro, na pilha de operandos*/
u1 iconst_3(u1* code) {
	u4 param = 3;
	push_op((u4) param);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
/*coloca a constante 4, do tipo inteiro, na pilha de operandos*/
u1 iconst_4(u1* code) {
	u4 param = 4;
	push_op((u4) param);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
/*coloca a constante 5, do tipo inteiro, na pilha de operandos*/
u1 iconst_5(u1* code) {
	u4 param = 5;
	push_op((u4) param);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

/*N�o implementado (long)*/
u1 lconst_0(u1* code) {
	push_op((u4) 0);
	push_op((u4) 0);

	++(FRAMESTACK->top->frame->pc);
	return 0;

}
/*Não implementado (long)*/
u1 lconst_1(u1* code) {

	push_op((u4) 1);
	push_op((u4) 0);

	++(FRAMESTACK->top->frame->pc);
	return 0;

}

/*coloca a constante 0, do tipo float, na pilha de operandos*/
u1 fconst_0(u1* code) {
	union {
		u4 param_int;
		float param_float;
	} aux;
	aux.param_float = 0.0;
	push_op(aux.param_int);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
/*coloca a constante 1, do tipo float, na pilha de operandos*/
u1 fconst_1(u1* code) {
	union {
		u4 param_int;
		float param_float;
	} aux;
	aux.param_float = 1.0;
	push_op(aux.param_int);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
/*coloca a constante 2, do tipo float, na pilha de operandos*/
u1 fconst_2(u1* code) {
	union {
		u4 param_int;
		float param_float;
	} aux;
	aux.param_float = 2.0;
	push_op(aux.param_int);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
/*N�o implementado (double)*/

u1 dconst_0(u1* code) {

	push_op((u4) 0);

	push_op((u4) 0);

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

/*N�o implementado (double)*/

u1 dconst_1(u1* code) {

	push_op((u4) 1);

	push_op((u4) 0);

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

/*o imediato de valor u1, do tipo byte, e extendido para um signed int que e colocado na pilha de operandos.*/
u1 bipush(u1* code) {
	s1 param;
	param = (s1) code[++(FRAMESTACK->top->frame->pc)];

	push_op((s4) param);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

/*os valores de param1 e param2 sao montados em um short com um vaolr de (param1 <<8) | param2)
 Esse valor � extendido e colocado na pilha de operandos.*/
u1 sipush(u1* code) {
	u2 param1, param2;
	param1 = (u2) code[++(FRAMESTACK->top->frame->pc)];
	param1 = param1 << 8;
	param2 = (u2) code[++(FRAMESTACK->top->frame->pc)];
	param1 = param1 + param2;
	push_op((u4) param1);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
/*o indice � um unsigned byte que deve ser um indice valido para o pool de constantes da classe atual
 se a entrada para o runtime constant pool for um inteiro ou um float, o valor nao � colocado na pilha
 Caso contrario, deve ser uma referencia para a uma instancia da classe String, que � colocada na pilha*/

u1 ldc(u1* code) {
	union {
		u4 param_int;
		float param_float;
		u4 param_byte;
	} aux;
	u1 entry, tag;

	entry = (u1) code[++(FRAMESTACK->top->frame->pc)];
	tag = MAINCLASS->constant_pool[entry - 1].tag;
	switch (tag) {
	case 0x03:
		aux.param_int = MAINCLASS->constant_pool[entry - 1].info.Integer.bytes;

		break;
	case 0x04:
		aux.param_int = MAINCLASS->constant_pool[entry - 1].info.Float.bytes;

		break;
	case 0x08:
		aux.param_int
				= MAINCLASS->constant_pool[entry - 1].info.String.string_index;
		break;
	default:
		printf("Operacao invalida, tag nao reconhecida \n");
	}
	push_op(aux.param_int);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
/*o indice � um unsigned byte que deve ser um indice valido para o pool de constantes da classe atual
 se a entrada para o runtime constant pool for um inteiro ou um float, o valor nao � colocado na pilha
 Caso contrario, deve ser uma referencia para a uma instancia da classe String, que � colocada na pilha*/

u1 ldc_w(u1* code) {
	union {
		u4 param_int;
		float param_float;
		u4 param_byte;
	} aux;
	u2 entry1, entry2;
	u1 tag;
	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 << 8;
	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 + entry2;
	tag = MAINCLASS->constant_pool[entry1 - 1].tag;
	switch (tag) {
	case 0x01:
		aux.param_int = MAINCLASS->constant_pool[entry1 - 1].info.Integer.bytes;
		break;
	case 0x03:
		aux.param_int = MAINCLASS->constant_pool[entry1 - 1].info.Float.bytes;
		break;
	case 0x08:
		aux.param_int
				= MAINCLASS->constant_pool[entry1 - 1].info.String.string_index;
		break;
	default:
		printf("Operacao invalida, tag nao reconhcedida");
	}
	push_op(aux.param_int);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 ldc2_w(u1* code) {

	u4 aux_low, aux_hi;

	u2 entry1, entry2;

	u1 tag;

	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];

	entry1 = entry1 << 8;

	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];

	entry1 = entry1 + entry2;

	tag = MAINCLASS->constant_pool[entry1 - 1].tag;

	switch (tag) {

	case 0x05:
		aux_hi = MAINCLASS->constant_pool[entry1 - 1].info.Long.high_bytes;

		aux_low = MAINCLASS->constant_pool[entry1 - 1].info.Long.low_bytes;

		break;

	case 0x06:
		aux_hi = MAINCLASS->constant_pool[entry1 - 1].info.Double.high_bytes;

		aux_low = MAINCLASS->constant_pool[entry1 - 1].info.Double.low_bytes;

		break;

	default:
		printf("Operacao invalida, tag nao reconhcedida");

	}

	push_op(aux_low);

	push_op(aux_hi);

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

/*O indice � um unsigned char que deve ser um indice para o vetor de variaveis locias do frame atual
 Essas variaveis locais devem ser do tipo inteiro e sao colocadas no topo da pilha*/

u1 iload(u1* code) {
	u1 param;
	param = (u1) code[++(FRAMESTACK->top->frame->pc)];
	push_op((s4) FRAMESTACK->top->frame->array[param]);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
/*(Long)*/
u1 lload(u1* code) {

	u1 param;
	param = (u1) code[++(FRAMESTACK->top->frame->pc)];
	push_op((s4) FRAMESTACK->top->frame->array[param + 1]);
	push_op((s4) FRAMESTACK->top->frame->array[param]);
	++(FRAMESTACK->top->frame->pc);
	return 0;

}
/*O indice � um unsigned char que deve ser um indice para o vcetor de variaveis locias do frame atual
 Essas variaveis locais devem ser do tipo float e sao colocadas no topo da pilha*/

u1 fload(u1* code) {
	u1 param;
	param = (u1) code[++(FRAMESTACK->top->frame->pc)];
	push_op((u4) FRAMESTACK->top->frame->array[param]);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

/*Doble*/

u1 dload(u1* code) {
	u1 param;

	param = (u1) code[++(FRAMESTACK->top->frame->pc)];

	push_op((s4) FRAMESTACK->top->frame->array[param + 1]);
	push_op((s4) FRAMESTACK->top->frame->array[param]);

	++(FRAMESTACK->top->frame->pc);

	return 0;

}
u1 aload(u1* code) {
	u1 param;
	param = (u1) code[++(FRAMESTACK->top->frame->pc)];
	push_op((u4) FRAMESTACK->top->frame->array[param]);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
/*Carrega o valor da vari�vel com index 0, para o topo da pilha do frame (operand stack).*/
u1 iload_0(u1* code) {
	push_op((u4) FRAMESTACK->top->frame->array[0]);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
/*Carrega o valor da vari�vel com index 1, para o topo da pilha do frame (operand stack).*/
u1 iload_1(u1* code) {
	push_op((u4) FRAMESTACK->top->frame->array[1]);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 iload_2(u1* code) {
	push_op((u4) FRAMESTACK->top->frame->array[2]);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 iload_3(u1* code) {
	push_op((u4) FRAMESTACK->top->frame->array[3]);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 lload_0(u1* code) {

	push_op((u4) FRAMESTACK->top->frame->array[1]);
	push_op((u4) FRAMESTACK->top->frame->array[0]);

	++(FRAMESTACK->top->frame->pc);
	return 0;

}
u1 lload_1(u1* code) {
	push_op((u4) FRAMESTACK->top->frame->array[2]);
	push_op((u4) FRAMESTACK->top->frame->array[1]);

	++(FRAMESTACK->top->frame->pc);
	return 0;

}
u1 lload_2(u1* code) {
	push_op((u4) FRAMESTACK->top->frame->array[3]);
	push_op((u4) FRAMESTACK->top->frame->array[2]);

	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 lload_3(u1* code) {
	push_op((u4) FRAMESTACK->top->frame->array[4]);
	push_op((u4) FRAMESTACK->top->frame->array[3]);

	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 fload_0(u1* code) {
	push_op((u4) FRAMESTACK->top->frame->array[0]);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 fload_1(u1* code) {
	push_op((u4) FRAMESTACK->top->frame->array[1]);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 fload_2(u1* code) {
	push_op((u4) FRAMESTACK->top->frame->array[2]);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 fload_3(u1* code) {
	push_op((u4) FRAMESTACK->top->frame->array[3]);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 dload_0(u1* code) {

	push_op((u4) FRAMESTACK->top->frame->array[1]);

	push_op((u4) FRAMESTACK->top->frame->array[0]);

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

u1 dload_1(u1* code) {

	push_op((u4) FRAMESTACK->top->frame->array[2]);

	push_op((u4) FRAMESTACK->top->frame->array[1]);

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

u1 dload_2(u1* code) {

	push_op((u4) FRAMESTACK->top->frame->array[3]);

	push_op((u4) FRAMESTACK->top->frame->array[2]);

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

u1 dload_3(u1* code) {

	push_op((u4) FRAMESTACK->top->frame->array[4]);

	push_op((u4) FRAMESTACK->top->frame->array[3]);

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

u1 aload_0(u1* code) {
	push_op((u4) FRAMESTACK->top->frame->array[0]);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 aload_1(u1* code) {
	push_op((u4) FRAMESTACK->top->frame->array[1]);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 aload_2(u1* code) {
	push_op((u4) FRAMESTACK->top->frame->array[2]);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 aload_3(u1* code) {
	push_op((u4) FRAMESTACK->top->frame->array[3]);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 iaload(u1* code) {
	exception(1);
	return 0;
}

u1 laload(u1* code) {
	exception(1);
	return 0;
}

u1 faload(u1* code) {
	exception(1);
	return 0;
}

u1 daload(u1* code) {
	exception(1);
	return 0;
}

u1 aaload(u1* code) {
	exception(1);
	return 0;
}

u1 baload(u1* code) {
	exception(1);
	return 0;
}

u1 caload(u1* code) {
	exception(1);
	return 0;
}

u1 saload(u1* code) {
	exception(1);
	return 0;
}

u1 istore(u1* code) {
	u1 param;
	param = (u1) code[++(FRAMESTACK->top->frame->pc)];
	FRAMESTACK->top->frame->array[param] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 lstore(u1* code) {
	u1 param;
	param = (u1) code[++(FRAMESTACK->top->frame->pc)];
	FRAMESTACK->top->frame->array[param] = pop_op();
	FRAMESTACK->top->frame->array[param + 1] = pop_op();

	++(FRAMESTACK->top->frame->pc);
	return 0;

}

u1 fstore(u1* code) {
	u1 param;
	param = (u1) code[++(FRAMESTACK->top->frame->pc)];
	FRAMESTACK->top->frame->array[param] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 dstore(u1* code) {

	u1 param;

	param = (u1) code[++(FRAMESTACK->top->frame->pc)];

	FRAMESTACK->top->frame->array[param] = pop_op();
	FRAMESTACK->top->frame->array[param + 1] = pop_op();

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

u1 astore(u1* code) {
	u1 param;
	param = (u1) code[++(FRAMESTACK->top->frame->pc)];
	FRAMESTACK->top->frame->array[param] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 istore_0(u1* code) {
	FRAMESTACK->top->frame->array[0] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 istore_1(u1* code) {
	FRAMESTACK->top->frame->array[1] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 istore_2(u1* code) {
	FRAMESTACK->top->frame->array[2] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 istore_3(u1* code) {
	FRAMESTACK->top->frame->array[3] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 lstore_0(u1* code) {

	FRAMESTACK->top->frame->array[0] = pop_op();
	FRAMESTACK->top->frame->array[1] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;

}
u1 lstore_1(u1* code) {
	FRAMESTACK->top->frame->array[1] = pop_op();
	FRAMESTACK->top->frame->array[2] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 lstore_2(u1* code) {
	FRAMESTACK->top->frame->array[2] = pop_op();
	FRAMESTACK->top->frame->array[3] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 lstore_3(u1* code) {
	FRAMESTACK->top->frame->array[3] = pop_op();
	FRAMESTACK->top->frame->array[4] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 fstore_0(u1* code) {
	FRAMESTACK->top->frame->array[0] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 fstore_1(u1* code) {
	FRAMESTACK->top->frame->array[1] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 fstore_2(u1* code) {
	FRAMESTACK->top->frame->array[2] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 fstore_3(u1* code) {
	FRAMESTACK->top->frame->array[3] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 dstore_0(u1* code) {

	FRAMESTACK->top->frame->array[0] = pop_op();

	FRAMESTACK->top->frame->array[1] = pop_op();

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

u1 dstore_1(u1* code) {

	FRAMESTACK->top->frame->array[1] = pop_op();

	FRAMESTACK->top->frame->array[2] = pop_op();

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

u1 dstore_2(u1* code) {

	FRAMESTACK->top->frame->array[2] = pop_op();

	FRAMESTACK->top->frame->array[3] = pop_op();

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

u1 dstore_3(u1* code) {

	FRAMESTACK->top->frame->array[3] = pop_op();

	FRAMESTACK->top->frame->array[4] = pop_op();

	++(FRAMESTACK->top->frame->pc);

	return 0;

}
u1 astore_0(u1* code) {
	FRAMESTACK->top->frame->array[0] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 astore_1(u1* code) {
	FRAMESTACK->top->frame->array[1] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 astore_2(u1* code) {
	FRAMESTACK->top->frame->array[2] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 astore_3(u1* code) {
	FRAMESTACK->top->frame->array[3] = pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 iastore(u1* code) {
	exception(1);
	return 0;
}

u1 lastore(u1* code) {
	exception(1);
	return 0;
}

u1 fastore(u1* code) {
	exception(1);
	return 0;
}

u1 dastore(u1* code) {
	exception(1);
	return 0;
}

u1 aastore(u1* code) {
	exception(1);
	return 0;
}

u1 bastore(u1* code) {
	exception(1);
	return 0;
}

u1 castore(u1* code) {
	exception(1);
	return 0;
}

u1 sastore(u1* code) {
	exception(1);
	return 0;
}
u1 pop(u1* code) {
	pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 pop2(u1* code) {
	pop_op();
	pop_op();
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 dup(u1* code) {
	u4 aux;
	aux = pop_op();
	push_op(aux);
	push_op(aux);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 dup_x1(u1* code) {
	u4 aux, aux2;
	aux = pop_op();
	aux2 = pop_op();
	push_op(aux);
	push_op(aux2);
	push_op(aux);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 dup_x2(u1* code) {
	u4 aux, aux2, aux3;
	aux = pop_op();
	aux2 = pop_op();
	aux3 = pop_op();
	push_op(aux);
	push_op(aux2);
	push_op(aux3);
	push_op(aux);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 dup2(u1* code) {
	u4 aux, aux2;
	aux = pop_op();
	aux2 = pop_op();
	push_op(aux2);
	push_op(aux);
	push_op(aux2);
	push_op(aux);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 dup2_x1(u1* code) {
	u4 aux, aux2, aux3;
	aux = pop_op();
	aux2 = pop_op();
	aux3 = pop_op();
	push_op(aux2);
	push_op(aux);
	push_op(aux3);
	push_op(aux2);
	push_op(aux);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 dup2_x2(u1* code) {
	u4 aux, aux2, aux3, aux4;
	aux = pop_op();
	aux2 = pop_op();
	aux3 = pop_op();
	aux4 = pop_op();
	push_op(aux2);
	push_op(aux);
	push_op(aux4);
	push_op(aux3);
	push_op(aux2);
	push_op(aux);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 swap(u1* code) {
	u4 aux, aux2;
	aux = pop_op();
	aux2 = pop_op();
	push_op(aux);
	push_op(aux2);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 iadd(u1* code) {
	s4 aux, aux2;
	aux = pop_op();
	aux2 = pop_op();
	push_op(aux + aux2);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 ladd(u1* code) {
	u4 aux1_hi, aux1_lo, soma_hi, soma_lo, aux2_hi, aux2_lo;
	u8 aux1, aux2, soma;

	aux2_hi = pop_op();
	aux2_lo = pop_op();

	aux1_hi = pop_op();
	aux1_lo = pop_op();

	aux1 = (u8) aux1_hi;
	aux1 = (aux1 << 32) | aux1_lo;

	aux2 = (u8) aux2_hi;
	aux2 = (aux2 << 32) | aux2_lo;

	soma = aux1 + aux2;

	soma_lo = soma & 0x00000000FFFFFFFF;
	soma_hi = soma >> 32;

	push_op(soma_lo);
	push_op(soma_hi);

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

u1 fadd(u1* code) {
	union {
		u4 param_int;
		float param_float;
	} aux, aux2;
	aux.param_int = pop_op();
	aux2.param_int = pop_op();
	aux.param_float = aux.param_float + aux2.param_float;
	push_op(aux.param_int);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 dadd(u1* code) {
	u4 aux1_hi, aux1_lo, soma_hi, soma_lo, aux2_hi, aux2_lo;
	u8 aux1, aux2, soma;
	double d1, d2, ds;

	aux2_hi = pop_op();
	aux2_lo = pop_op();

	aux1_hi = pop_op();
	aux1_lo = pop_op();

	aux1 = (u8) aux1_hi;
	aux1 = (aux1 << 32) | aux1_lo;

	aux2 = (u8) aux2_hi;
	aux2 = (aux2 << 32) | aux2_lo;

	memcpy(&d1, &aux1, 8);
	memcpy(&d2, &aux2, 8);

	ds = d1 + d2;

	memcpy(&ds, &soma, 8);

	soma_lo = soma & 0x00000000FFFFFFFF;
	soma_hi = soma >> 32;

	push_op(soma_lo);
	push_op(soma_hi);

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

u1 isub(u1* code) {
	u4 aux, aux2;
	aux = pop_op();
	aux2 = pop_op();
	push_op(aux2 - aux);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 lsub(u1* code) {
	u4 aux1_hi, aux1_lo, soma_hi, soma_lo, aux2_hi, aux2_lo;
	u8 aux1, aux2, soma;

	aux2_hi = pop_op();
	aux2_lo = pop_op();

	aux1_hi = pop_op();
	aux1_lo = pop_op();

	aux1 = (u8) aux1_hi;
	aux1 = (aux1 << 32) | aux1_lo;

	aux2 = (u8) aux2_hi;
	aux2 = (aux2 << 32) | aux2_lo;

	soma = aux1 - aux2;

	soma_lo = soma & 0x00000000FFFFFFFF;
	soma_hi = soma >> 32;

	push_op(soma_lo);
	push_op(soma_hi);

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

u1 fsub(u1* code) {
	union {
		u4 param_int;
		float param_float;
	} aux, aux2;
	aux.param_int = pop_op();
	aux2.param_int = pop_op();
	aux.param_float = aux2.param_float - aux.param_float;
	push_op(aux.param_int);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 dsub(u1* code) {
	u4 aux1_lo, aux1_hi, soma_lo, soma_hi, aux2_lo, aux2_hi;
	double aux1, aux2, soma;

	aux2_hi = pop_op();
	aux2_lo = pop_op();

	aux1_hi = pop_op();
	aux1_lo = pop_op();

	memcpy(&aux1, &aux1_lo, 8);

	memcpy(&aux2, &aux2_lo, 8);

	soma = aux1 + aux2;

	memcpy(&aux1_lo, &aux1, 8);

	memcpy(&aux2_lo, &aux2, 8);

	push_op(soma_lo);
	push_op(soma_hi);

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

u1 imul(u1* code) {
	u4 aux, aux2;
	aux = pop_op();
	aux2 = pop_op();
	push_op(aux * aux2);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 lmul(u1* code) {
	u4 aux1_hi, aux1_lo, resultado_hi, resultado_lo, aux2_hi, aux2_lo;
	u8 aux1, aux2, resultado;

	aux2_hi = pop_op();
	aux2_lo = pop_op();

	aux1_hi = pop_op();
	aux1_lo = pop_op();

	aux1 = (u8) aux1_hi;
	aux1 = (aux1 << 32) | aux1_lo;

	aux2 = (u8) aux2_hi;
	aux2 = (aux2 << 32) | aux2_lo;

	resultado = aux1 * aux2;
	resultado_lo = resultado & 0x00000000FFFFFFFF;
	resultado_hi = resultado >> 32;

	push_op(resultado_lo);
	push_op(resultado_hi);

	++(FRAMESTACK->top->frame->pc);

	return 0;
}

u1 fmul(u1* code) {
	union {
		u4 param_int;
		float param_float;
	} aux, aux2;
	aux.param_int = pop_op();
	aux2.param_int = pop_op();
	aux.param_float = aux.param_float * aux2.param_float;
	push_op(aux.param_int);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 dmul(u1* code) {

	union {

		u4 param_int;

		float param_float;

	} aux1_hi, aux1_lo, soma_hi, soma_lo, aux2_hi, aux2_lo;

	u8 aux1, aux2;

	u8 resultado;

	aux2_hi.param_float = pop_op();

	aux2_lo.param_float = pop_op();

	aux1_hi.param_float = pop_op();

	aux1_lo.param_float = pop_op();

	aux1 = (u8) aux1_hi.param_float; /*parte baixa*/

	aux1 = (aux1 << 32) + aux1_lo.param_float;

	aux2 = (u8) aux2_hi.param_float; /*parte alta*/

	aux2 = (aux2 << 32) + aux2_lo.param_float;

	resultado = aux1 * aux2;

	soma_lo.param_float = (s4) ((resultado << 32) >> 32); /*assumindo a parte baixa*/

	soma_hi.param_float = (s4) (resultado >> 32);

	push_op(soma_lo.param_float);

	push_op(soma_hi.param_float);

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

u1 idiv(u1* code) {
	u4 aux, aux2;
	aux = pop_op();
	aux2 = pop_op();
	push_op((aux2 / aux));
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 _ldiv(u1* code) {
	u4 aux1_hi, aux1_lo, resultado_hi, resultado_lo, aux2_hi, aux2_lo;
	u8 aux1, aux2, resultado;

	aux2_hi = pop_op();
	aux2_lo = pop_op();

	aux1_hi = pop_op();
	aux1_lo = pop_op();

	aux1 = (u8) aux1_hi;
	aux1 = (aux1 << 32) | aux1_lo;

	aux2 = (u8) aux2_hi;
	aux2 = (aux2 << 32) | aux2_lo;

	resultado = aux1 / aux2;

	resultado_lo = resultado & 0x00000000FFFFFFFF;
	resultado_hi = resultado >> 32;

	push_op(resultado_lo);
	push_op(resultado_hi);

	++(FRAMESTACK->top->frame->pc);

	return 0;
}

u1 fdiv(u1* code) {
	union {
		u4 param_int;
		float param_float;
	} aux, aux2;
	aux.param_int = pop_op();
	aux2.param_int = pop_op();
	aux.param_float = aux2.param_float / aux.param_float;
	push_op(aux.param_int);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 ddiv(u1* code) {

	union {

		u4 param_int;

		float param_float;

	} aux1_hi, aux1_lo, soma_hi, soma_lo, aux2_hi, aux2_lo;

	u8 aux1, aux2;

	u8 resultado;

	aux2_hi.param_float = pop_op();

	aux2_lo.param_float = pop_op();

	aux1_hi.param_float = pop_op();

	aux1_lo.param_float = pop_op();

	aux1 = (u8) aux1_hi.param_float; /*parte baixa*/

	aux1 = (aux1 << 32) + aux1_lo.param_float;

	aux2 = (u8) aux2_hi.param_float; /*parte alta*/

	aux2 = (aux2 << 32) + aux2_lo.param_float;

	resultado = aux1 / aux2;

	soma_lo.param_float = (s4) ((resultado << 32) >> 32); /*assumindo a parte baixa*/

	soma_hi.param_float = (s4) (resultado >> 32);

	push_op(soma_lo.param_float);

	push_op(soma_hi.param_float);

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

u1 irem(u1* code) {
	u4 aux, aux2;
	aux = pop_op();
	aux2 = pop_op();
	push_op((aux2 % aux));
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 lrem(u1* code) {
	u4 aux1_hi, aux1_lo, resultado_hi, resultado_lo, aux2_hi, aux2_lo;
	u8 aux1, aux2, resultado;

	aux1_hi = pop_op();
	aux1_lo = pop_op();

	aux2_hi = pop_op();
	aux2_lo = pop_op();

	aux1 = (u8) aux1_hi;
	aux1 = (aux1 << 32) | aux1_lo;

	aux2 = (u8) aux2_hi;
	aux2 = (aux2 << 32) | aux2_lo;

	resultado = aux2 % aux1;
	resultado_lo = resultado & 0x00000000FFFFFFFF;
	resultado_hi = resultado >> 32;

	push_op(resultado_lo);
	push_op(resultado_hi);

	++(FRAMESTACK->top->frame->pc);

	return 0;
}

u1 frem(u1* code) {
	union {
		u4 param_int;
		float param_float;
	} aux, aux2;
	aux.param_int = pop_op();
	aux2.param_int = pop_op();
	aux.param_float = fmod(aux2.param_float, aux.param_float);
	push_op(aux.param_int);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 _drem(u1* code) {

	union {

		u4 param_int;

		float param_float;

	} aux1_hi, aux1_lo, soma_hi, soma_lo, aux2_hi, aux2_lo;

	u8 aux1, aux2;

	u8 resultado;

	aux2_hi.param_float = pop_op();

	aux2_lo.param_float = pop_op();

	aux1_hi.param_float = pop_op();

	aux1_lo.param_float = pop_op();

	aux1 = (u8) aux1_hi.param_float; /*parte baixa*/

	aux1 = (aux1 << 32) + aux1_lo.param_float;

	aux2 = (u8) aux2_hi.param_float; /*parte alta*/

	aux2 = (aux2 << 32) + aux2_lo.param_float;

	resultado = aux1 % aux2;

	soma_lo.param_float = (s4) ((resultado << 32) >> 32); /*assumindo a parte baixa*/

	soma_hi.param_float = (s4) (resultado >> 32);

	push_op(soma_lo.param_float);

	push_op(soma_hi.param_float);

	++(FRAMESTACK->top->frame->pc);

	return 0;

}

u1 ineg(u1* code) {
	u4 aux;
	aux = pop_op();
	push_op((aux * (-1)));
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 lneg(u1* code) {
	u4 aux1_hi, aux1_lo, resultado_hi, resultado_lo;
	u8 aux1, resultado;

	aux1_hi = pop_op();
	aux1_lo = pop_op();

	aux1 = (u8) aux1_hi;
	aux1 = (aux1 << 32) | aux1_lo;

	resultado = -aux1;

	resultado_lo = resultado & 0x00000000FFFFFFFF;
	resultado_hi = resultado >> 32;

	push_op(resultado_lo);
	push_op(resultado_hi);

	++(FRAMESTACK->top->frame->pc);

	return 0;
}

u1 fneg(u1* code) {
	union {
		u4 param_int;
		float param_float;
	} aux;
	aux.param_int = pop_op();
	aux.param_float = aux.param_float * (-1);
	push_op(aux.param_int);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 dneg(u1* code) {
	exception(1);
	return 0;
}
u1 ishl(u1* code) {
	u4 aux, aux2;
	aux = pop_op();
	aux2 = pop_op();
	aux = aux & 31;
	aux2 = aux2 << aux;
	push_op(aux2);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 lshl(u1* code) {
	exception(1);
	return 0;
}

u1 ishr(u1* code) {
	int aux, aux2, aux3;
	aux = pop_op();
	aux2 = pop_op();
	aux3 = aux & 128;
	aux2 = aux2 & 31;
	aux >>= aux2;
	aux = aux & aux3;
	push_op(aux);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 lshr(u1* code) {
	exception(1);
	return 0;
}

u1 iushr(u1* code) {
	int aux, aux2;
	aux = pop_op();
	aux2 = pop_op();
	aux2 = aux2 & 31;
	aux >>= aux2;
	push_op(aux);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 lushr(u1* code) {
	exception(1);
	return 0;
}

u1 iand(u1* code) {
	int aux, aux2;
	aux = pop_op();
	aux2 = pop_op();
	aux &= aux2;
	push_op(aux);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 land(u1* code) {
	exception(1);
	return 0;
}

u1 ior(u1* code) {
	int aux, aux2;
	aux = pop_op();
	aux2 = pop_op();
	aux |= aux2;
	push_op(aux);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 lor(u1* code) {
	exception(1);
	return 0;
}

u1 ixor(u1* code) {
	int aux, aux2;
	aux = pop_op();
	aux2 = pop_op();
	aux ^= aux2;
	push_op(aux);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 lxor(u1* code) {
	exception(1);
	return 0;
}

u1 iinc(u1* code) {
	u1 param;
	s1 param2;
	param = (u1) code[++(FRAMESTACK->top->frame->pc)];
	param2 = (s1) code[++(FRAMESTACK->top->frame->pc)];
	FRAMESTACK->top->frame->array[param] = FRAMESTACK->top->frame->array[param]
			+ param2;

	++(FRAMESTACK->top->frame->pc);
	return 0;
}
u1 i2l(u1* code) {
	exception(1);
	return 0;
}

u1 i2f(u1* code) {
	u4 param_aux;
	union {
		u4 param_int;
		float param_float;
	} aux;
	param_aux = pop_op();
	aux.param_float = (float) param_aux;
	push_op(aux.param_int);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 i2d(u1* code) {
	exception(1);
	return 0;
}

u1 l2i(u1* code) {
	exception(1);
	return 0;
}

u1 l2f(u1* code) {
	exception(1);
	return 0;
}

u1 l2d(u1* code) {
	exception(1);
	return 0;
}

u1 f2i(u1* code) {
	u4 param_int;
	union {
		u4 param_int;
		float param_float;
	} aux;

	aux.param_int = pop_op();
	param_int = (int) aux.param_float;
	push_op(param_int);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 f2l(u1* code) {
	exception(1);
	return 0;
}

u1 f2d(u1* code) {
	exception(1);
	return 0;
}

u1 d2i(u1* code) {
	exception(1);
	return 0;
}

u1 d2l(u1* code) {
	exception(1);
	return 0;
}

u1 d2f(u1* code) {
	exception(1);
	return 0;
}

u1 i2b(u1* code) {
	u4 param_int;
	u1 param_byte;
	param_int = pop_op();
	param_byte = (u1) param_int;
	push_op((u4) param_byte);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 i2c(u1* code) {
	u4 param_int;
	u2 param_char;
	param_int = pop_op();
	param_char = (u2) param_int;
	push_op((u4) param_char);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 i2s(u1* code) {
	u4 param_int;
	u2 param_short;
	param_int = pop_op();
	param_short = (u2) param_int;
	push_op((u4) param_short);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 lcmp(u1* code) {
	u4 aux1_hi, aux1_lo, aux2_hi, aux2_lo;
	u8 aux1, aux2;

	aux2_hi = pop_op();
	aux2_lo = pop_op();

	aux1_hi = pop_op();
	aux1_lo = pop_op();

	aux1 = (u8) aux1_hi;
	aux1 = (aux1 << 32) | aux1_lo;

	aux2 = (u8) aux2_hi;
	aux2 = (aux2 << 32) | aux2_lo;

	if (aux1 > aux2) push_op((u4) (1));
	else if (aux1 < aux2) push_op((u4) (-1));
	else if (aux1 == aux2) push_op((u4) 0);

	++(FRAMESTACK->top->frame->pc);

	return 0;
}

u1 fcmpl(u1* code) {
	union {
		u4 param_int;
		float param_float;
	} aux, aux2;
	aux.param_int = pop_op();
	aux2.param_int = pop_op();
	if (aux2.param_float > aux.param_float) push_op((u4) (1));
	else if (aux2.param_float < aux.param_float) push_op((u4) (-1));
	else if (aux2.param_float == aux.param_float) push_op((u4) 0);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 fcmpg(u1* code) {
	union {
		u4 param_int;
		float param_float;
	} aux, aux2;
	aux.param_int = pop_op();
	aux2.param_int = pop_op();
	if (aux2.param_float > aux.param_float) push_op((u4) (1));
	else if (aux2.param_float < aux.param_float) push_op((u4) (-1));
	else if (aux2.param_float == aux.param_float) push_op((u4) 0);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 dcmpl(u1* code) {
	exception(1);
	return 0;
}
u1 dcmpg(u1* code) {
	exception(1);
	return 0;
}

u1 ifeq(u1* code) {
	u4 zero;
	short int branchbyte1, branchbyte2;
	zero = pop_op();
	branchbyte1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	branchbyte1 = (branchbyte1 << 8);
	branchbyte2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	branchbyte1 = branchbyte1 + branchbyte2;
	if (zero == 0) {
		FRAMESTACK->top->frame->pc -= 2;
		FRAMESTACK->top->frame->pc = FRAMESTACK->top->frame->pc + branchbyte1;

		return 0;
	} else {
		++(FRAMESTACK->top->frame->pc);
		return 0;
	}

}
u1 ifne(u1* code) {
	u4 zero;
	short int branchbyte1, branchbyte2;
	zero = pop_op();
	branchbyte1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	branchbyte1 = (branchbyte1 << 8);
	branchbyte2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	branchbyte1 = branchbyte1 + branchbyte2;
	if (zero != 0) {
		FRAMESTACK->top->frame->pc -= 2;
		FRAMESTACK->top->frame->pc = FRAMESTACK->top->frame->pc + branchbyte1;

		return 0;
	} else {
		++(FRAMESTACK->top->frame->pc);
		return 0;
	}

}
u1 iflt(u1* code) {
	s4 aux;
	short int branchbyte1, branchbyte2;
	aux = pop_op();
	branchbyte1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	branchbyte1 = (branchbyte1 << 8);
	branchbyte2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	branchbyte1 = branchbyte1 + branchbyte2;
	if (aux < 0) {
		FRAMESTACK->top->frame->pc -= 2;
		FRAMESTACK->top->frame->pc = FRAMESTACK->top->frame->pc + branchbyte1;

		return 0;
	} else {
		++(FRAMESTACK->top->frame->pc);
		return 0;
	}

}
u1 ifge(u1* code) {
	s4 aux;
	short int branchbyte1, branchbyte2;
	aux = pop_op();
	branchbyte1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	branchbyte1 = (branchbyte1 << 8);
	branchbyte2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	branchbyte1 = branchbyte1 + branchbyte2;
	if (aux >= 0) {
		FRAMESTACK->top->frame->pc -= 2;
		FRAMESTACK->top->frame->pc = FRAMESTACK->top->frame->pc + branchbyte1;
		return 0;
	} else {
		++(FRAMESTACK->top->frame->pc);
		return 0;
	}

}
u1 ifgt(u1* code) {
	s4 aux;
	short int branchbyte1, branchbyte2;
	aux = pop_op();
	branchbyte1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	branchbyte1 = (branchbyte1 << 8);
	branchbyte2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	branchbyte1 = branchbyte1 + branchbyte2;
	if (aux > 0) {
		FRAMESTACK->top->frame->pc -= 2;
		FRAMESTACK->top->frame->pc = FRAMESTACK->top->frame->pc + branchbyte1;

		return 0;
	} else {
		++(FRAMESTACK->top->frame->pc);
		return 0;
	}

}
u1 ifle(u1* code) {
	s4 aux;
	short int branchbyte1, branchbyte2;
	aux = pop_op();
	branchbyte1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	branchbyte1 = (branchbyte1 << 8);
	branchbyte2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	branchbyte1 = branchbyte1 + branchbyte2;
	if ((int) aux <= 0) {
		FRAMESTACK->top->frame->pc -= 2;
		FRAMESTACK->top->frame->pc = FRAMESTACK->top->frame->pc + branchbyte1;
		return 0;
	} else {
		++(FRAMESTACK->top->frame->pc);
		return 0;
	}

}

u1 if_icmpeq(u1* code) {
	short int entry1, entry2;
	u4 aux1, aux2;

	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 << 8;
	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 + entry2;
	aux2 = pop_op();
	aux1 = pop_op();
	if (aux1 == aux2) {
		(FRAMESTACK->top->frame->pc) -= 2;
		(FRAMESTACK->top->frame->pc) += entry1;
	} else {
		++(FRAMESTACK->top->frame->pc);
	}

	return 0;
}

u1 if_icmpne(u1* code) {
	short int entry1, entry2;
	u4 aux1, aux2;

	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 << 8;
	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 + entry2;
	aux2 = pop_op();
	aux1 = pop_op();
	if (aux1 != aux2) {
		(FRAMESTACK->top->frame->pc) -= 2;
		(FRAMESTACK->top->frame->pc) += entry1;
	} else {
		++(FRAMESTACK->top->frame->pc);
	}
	return 0;
}

u1 if_icmplt(u1* code) {
	short int entry1, entry2;
	u4 aux1, aux2;

	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 << 8;
	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 + entry2;
	aux2 = pop_op();
	aux1 = pop_op();
	if (aux1 < aux2) {
		(FRAMESTACK->top->frame->pc) -= 2;
		(FRAMESTACK->top->frame->pc) += entry1;
	} else {
		++(FRAMESTACK->top->frame->pc);
	}

	return 0;
}

u1 if_icmpge(u1* code) {
	short int entry1, entry2;
	u4 aux1, aux2;

	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 << 8;
	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 + entry2;
	aux2 = pop_op();
	aux1 = pop_op();
	if (aux1 >= aux2) {
		(FRAMESTACK->top->frame->pc) -= 2;
		(FRAMESTACK->top->frame->pc) += entry1;
	} else {
		++(FRAMESTACK->top->frame->pc);
	}
	return 0;
}

u1 if_icmpgt(u1* code) {
	short int entry1, entry2;
	u4 aux1, aux2;

	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 << 8;
	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 + entry2;
	aux2 = pop_op();
	aux1 = pop_op();
	if (aux1 > aux2) {
		(FRAMESTACK->top->frame->pc) -= 2;
		(FRAMESTACK->top->frame->pc) += entry1;
	} else {
		++(FRAMESTACK->top->frame->pc);
	}
	return 0;
}

u1 if_icmple(u1* code) {
	short int entry1, entry2;
	u4 aux1, aux2;

	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 << 8;
	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 + entry2;
	aux2 = pop_op();
	aux1 = pop_op();
	if (aux1 <= aux2) {
		(FRAMESTACK->top->frame->pc) -= 2;
		(FRAMESTACK->top->frame->pc) += entry1;
	} else {
		++(FRAMESTACK->top->frame->pc);
	}
	return 0;
}

u1 if_acmpeq(u1* code) {
	short int entry1, entry2;
	u4 aux1, aux2;

	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 << 8;
	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 + entry2;
	aux2 = pop_op();
	aux1 = pop_op();
	if (aux1 == aux2) {
		(FRAMESTACK->top->frame->pc) -= 2;
		(FRAMESTACK->top->frame->pc) += entry1;
	} else {
		++(FRAMESTACK->top->frame->pc);
	}
	return 0;
}

u1 if_acmpne(u1* code) {
	short int entry1, entry2;
	u4 aux1, aux2;

	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 << 8;
	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 + entry2;
	aux2 = pop_op();
	aux1 = pop_op();
	if (aux1 != aux2) {
		(FRAMESTACK->top->frame->pc) -= 2;
		(FRAMESTACK->top->frame->pc) += entry1;
	} else {
		++(FRAMESTACK->top->frame->pc);
	}
	return 0;
}

u1 _goto(u1* code) {
	short int entry1, entry2;

	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 << 8;
	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 + entry2;

	(FRAMESTACK->top->frame->pc) -= 2;
	(FRAMESTACK->top->frame->pc) += entry1;
	return 0;
}
u1 jsr(u1* code) {
	exception(1);
	return 0;
}

u1 ret(u1* code) {
	exception(1);
	return 0;
}

u1 tableswitch(u1* code) {
	exception(1);
	return 0;
}

u1 lookupswitch(u1* code) {
	exception(1);
	return 0;
}
u1 ireturn(u1* code) {
	u4 ret;
	ret = pop_op();
	while (FRAMESTACK->top->frame->stack != FRAMESTACK->top->frame->base) {
		pop_op();
	}
	++(FRAMESTACK->top->frame->pc);
	pop_stack(FRAMESTACK);
	push_op(ret);
	return 1;
}
u1 lreturn(u1* code) {

	u4 ret1, ret2;
	ret1 = pop_op();
	ret2 = pop_op();

	while (FRAMESTACK->top->frame->stack != FRAMESTACK->top->frame->base) {
		pop_op();
	}

	++(FRAMESTACK->top->frame->pc);

	pop_stack(FRAMESTACK);

	puts("antes do push");
	push_op(ret2);
	push_op(ret1);
	puts("depois do push");

	return 1;

}

u1 freturn(u1* code) {
	u4 ret;
	ret = pop_op();
	while (FRAMESTACK->top->frame->stack != FRAMESTACK->top->frame->base) {
		pop_op();
	}
	++(FRAMESTACK->top->frame->pc);
	pop_stack(FRAMESTACK);
	push_op(ret);
	return 1;
}

u1 dreturn(u1* code) {

	u4 ret1, ret2;
	ret1 = pop_op();
	ret2 = pop_op();

	while (FRAMESTACK->top->frame->stack != FRAMESTACK->top->frame->base) {
		pop_op();
	}
	++(FRAMESTACK->top->frame->pc);
	pop_stack(FRAMESTACK);

	push_op(ret2);
	push_op(ret1);

	return 1;
}

u1 areturn(u1* code) {
	u4 ret;
	ret = pop_op();
	while (FRAMESTACK->top->frame->stack != FRAMESTACK->top->frame->base) {
		pop_op();
	}
	++(FRAMESTACK->top->frame->pc);
	pop_stack(FRAMESTACK);
	push_op(ret);
	return 1;
}
u1 _return(u1* code) {
	while (FRAMESTACK->top->frame->stack != FRAMESTACK->top->frame->base) {
		pop_op();
	}
	++(FRAMESTACK->top->frame->pc);
	pop_stack(FRAMESTACK);
	return 1;
}

u1 getstatic(u1* code) {
	int achou;
	class_field_node *pointer;
	u2 entry1, entry2;
	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 << 8;
	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 + entry2;

	pointer = MAINCLASS->class_fields;
	achou = 0;

	for (; (!achou) && (pointer); pointer = pointer->next) {
		if (pointer->cp_ref == entry1) {
			push_op(pointer->value);
			achou = 1;
		}
	}
	if (!achou) {
		push_op(0);
		/*printf("variavel estatica nao encontrada\n");
		 exit(1);*/
	}

	++(FRAMESTACK->top->frame->pc);
	return 0;

}
u1 putstatic(u1* code) {
	int achou;
	class_field_node *pointer;
	u2 entry1, entry2;

	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 << 8;
	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 + entry2;

	pointer = MAINCLASS->class_fields;
	achou = 0;

	for (; (!achou) && (pointer); pointer = pointer->next) {
		if (pointer->cp_ref == entry1) {
			pointer->value = pop_op();
			achou = 1;

		}
	}
	if (!achou) {
		class_field_node *novo = (class_field_node*) calloc(1,
				sizeof(class_field_node));
		novo->cp_ref = entry1;
		novo->value = pop_op();
		novo->next = MAINCLASS->class_fields;
		MAINCLASS->class_fields = novo;
	}

	++(FRAMESTACK->top->frame->pc);
	return 0;

}
u1 getfield(u1* code) {
	exception(1);
	return 0;
}
u1 putfield(u1* code) {
	exception(1);
	return 0;
}

u1 invokevirtual(u1* code) {
	u2 entry1, entry2;
	u2 c_index, c_n_index, n_t_index, d_index, n_index;
	u4 method_name_index = 0, descriptor_length = 0;
	u4 i = 0;
	int *j = (int*) calloc(1, sizeof(int));
	u1 *descriptor;
	u1 *method_name;
	u1 *class_name;
	u1 *class_name_ext;
	method_info *method;
	method_frame *m_frame;
	u4 *array;
	class_file *class;

	union intfloat print_out, print_out2;
	s8 long_result;
	double double_result;


	/* calcula entrada para o pool de constantes com o nome do metodo a ser invocado */
	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 << 8;
	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 + entry2;

	c_index = MAINCLASS->constant_pool[entry1 - 1].info.Methodref.class_index; /* encontra referencia no p.c. para classe do metodo */

	c_n_index = MAINCLASS->constant_pool[c_index - 1].info.Class.name_index; /* encontra referencia no p.c. para nome da classe */

	class_name = MAINCLASS->constant_pool[c_n_index - 1].info.Utf8.bytes;

	n_t_index
			= FRAMESTACK->top->frame->constant_pool[entry1 - 1].info.Methodref.name_and_type_index; /* encontra referencia no p.c. para nome e descritor  do metodo */
	n_index
			= FRAMESTACK->top->frame->constant_pool[n_t_index - 1].info.NameAndType.name_index; /* encontra referencia para o nome do metodo */
	d_index
			= FRAMESTACK->top->frame->constant_pool[n_t_index - 1].info.NameAndType.descriptor_index; /* encontra referencia para o descritor do metodo */

	method_name
			= FRAMESTACK->top->frame->constant_pool[n_index - 1].info.Utf8.bytes;

	if ((!strcmp("print", (char*) method_name)) || (!strcmp("println",
			(char*) method_name))) {

		print_out.inteiro = pop_op();

		if (!strcmp(
				"(Ljava/lang/String;)V",
				(char*) FRAMESTACK->top->frame->constant_pool[d_index - 1].info.Utf8.bytes)) {
			for (i = 0; i
					< FRAMESTACK->top->frame->constant_pool[print_out.inteiro
							- 1].info.Utf8.lenght; i++) {
				printf(
						"%c",
						(char) FRAMESTACK->top->frame->constant_pool[print_out.inteiro
								- 1].info.Utf8.bytes[i]);
			}
		} /*Imprime float*/
		else if (!strcmp(
				"(F)V",
				(char*) FRAMESTACK->top->frame->constant_pool[d_index - 1].info.Utf8.bytes)) {
			printf("%f", print_out.flutuante);
		} else if (!strcmp(
				"(J)V",
				(char*) FRAMESTACK->top->frame->constant_pool[d_index - 1].info.Utf8.bytes)) {

			print_out2.inteiro = pop_op();

			long_result = (s8) print_out.inteiro << 32;

			long_result = long_result | (s8) print_out2.inteiro;

			printf("%lld", long_result);

		} else if (!strcmp(
						"(D)V",
						(char*) FRAMESTACK->top->frame->constant_pool[d_index - 1].info.Utf8.bytes)) {

			print_out2.inteiro = pop_op();
			print_out.inteiro = pop_op();
			memcpy(&double_result, &print_out, 8);
			printf("%f", double_result);

		} else {
			printf("%d", print_out.inteiro);
		} /*Caso for println, pular a linha*/
		if (!strcmp("println", (char*) method_name)) printf("\n");
		pop_op();
	} else {
		/* busca por classe em METHODAREA */
		class_name_ext = (u1*) calloc(strlen((char*) class_name) + 6,
				sizeof(u1));
		strcpy((char*) class_name_ext, (char*) class_name);
		strcat((char*) class_name_ext, ".class");
		/* busca o arquivo .class no diretorio atual */
		loadClass((char*) class_name_ext);
		class = (class_file *) get_class(METHODAREA, (char*) class_name_ext);

		for (i = 0; i < class->methods_count; i++) {
			method_name_index = class->methods[i].name_index - 1;
			if (!strcmp(
					(char *) method_name,
					(char *) class->constant_pool[method_name_index].info.Utf8.bytes)) {
				break;
			}
		}
		/* arquivo .class nao possui metodo metodo invocado */
		if (i == class->methods_count) {
			printf("method not found: cannot execute\n");
			exit(0);
		} else {
			method = &(class->methods[i]);
		}
		m_frame = (method_frame *) new_frame(method, class->constant_pool, i);
		descriptor = class->constant_pool[d_index - 1].info.Utf8.bytes;
		descriptor_length = class->constant_pool[d_index - 1].info.Utf8.lenght;
		array = descriptor_parser(descriptor, descriptor_length, j);


		/* array[0] recebe referencia ao objeto */
		push_stack(FRAMESTACK, m_frame);
		FRAMESTACK->top->frame->array[0] = pop_op();
		for (i = 1; i < (*j); i++)
			FRAMESTACK->top->frame->array[i] = array[i];

		execute(FRAMESTACK->top->frame, class);
	}
	++(FRAMESTACK->top->frame->pc);
	return 0;

}

u1 invokespecial(u1* code) {
	u2 entry1, entry2;
	u2 c_index, c_n_index, n_t_index, d_index, n_index;
	u4 method_name_index = 0, descriptor_length = 0;
	u4 i = 0;
	int *j = (int*) calloc(1, sizeof(int));
	u1 *descriptor;
	u1 *method_name;
	u1 *class_name;
	u1 *class_name_ext;
	method_info *method;
	method_frame *m_frame;
	u4 *array;
	class_file *class;
	union intfloat print_out;
	/* calcula entrada para o pool de constantes com o nome do metodo a ser invocado */
	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 << 8;
	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 + entry2;

	c_index = MAINCLASS->constant_pool[entry1 - 1].info.Methodref.class_index; /* encontra referencia no p.c. para classe do metodo */

	c_n_index = MAINCLASS->constant_pool[c_index - 1].info.Class.name_index; /* encontra referencia no p.c. para nome da classe */

	class_name = MAINCLASS->constant_pool[c_n_index - 1].info.Utf8.bytes;

	n_t_index
			= FRAMESTACK->top->frame->constant_pool[entry1 - 1].info.Methodref.name_and_type_index; /* encontra referencia no p.c. para nome e descritor  do metodo */
	n_index
			= FRAMESTACK->top->frame->constant_pool[n_t_index - 1].info.NameAndType.name_index; /* encontra referencia para o nome do metodo */
	d_index
			= FRAMESTACK->top->frame->constant_pool[n_t_index - 1].info.NameAndType.descriptor_index; /* encontra referencia para o descritor do metodo */

	method_name
			= FRAMESTACK->top->frame->constant_pool[n_index - 1].info.Utf8.bytes;

	if ((!strcmp("print", (char*) method_name)) || (!strcmp("println",
			(char*) method_name))) {

		print_out.inteiro = pop_op();

		if (!strcmp(
				"(Ljava/lang/String;)V",
				(char*) FRAMESTACK->top->frame->constant_pool[d_index - 1].info.Utf8.bytes)) {
			for (i = 0; i
					< FRAMESTACK->top->frame->constant_pool[print_out.inteiro
							- 1].info.Utf8.lenght; i++) {
				printf(
						"%c",
						(char) FRAMESTACK->top->frame->constant_pool[print_out.inteiro
								- 1].info.Utf8.bytes[i]);
			}
		} /*Imprime float*/
		else if (!strcmp(
				"(F)V",
				(char*) FRAMESTACK->top->frame->constant_pool[d_index - 1].info.Utf8.bytes)) {
			printf("%f", print_out.flutuante);
		} else {
			printf("%d", print_out.inteiro);
		} /*Caso for println, pular a linha*/
		if (!strcmp("println", (char*) method_name)) printf("\n");
		pop_op();
	} else {
		/* busca por classe em METHODAREA */
		class_name_ext = (u1*) calloc(strlen((char*) class_name) + 6,
				sizeof(u1));
		strcpy((char*) class_name_ext, (char*) class_name);
		strcat((char*) class_name_ext, ".class");
		/* busca o arquivo .class no diretorio atual */
		loadClass((char*) class_name_ext);
		class = (class_file *) get_class(METHODAREA, (char*) class_name_ext);

		for (i = 0; i < class->methods_count; i++) {
			method_name_index = class->methods[i].name_index - 1;
			if (!strcmp(
					(char *) method_name,
					(char *) class->constant_pool[method_name_index].info.Utf8.bytes)) {
				break;
			}
		}
		/* arquivo .class nao possui metodo metodo invocado */
		if (i == class->methods_count) {
			printf("method not found: cannot execute\n");
			exit(0);
		} else {
			method = &(class->methods[i]);
		}

		m_frame = (method_frame *) new_frame(method, class->constant_pool, i);
		descriptor = class->constant_pool[d_index - 1].info.Utf8.bytes;
		descriptor_length = class->constant_pool[d_index - 1].info.Utf8.lenght;
		array = descriptor_parser(descriptor, descriptor_length, j);
		/* array[0] recebe referencia ao objeto */
		push_stack(FRAMESTACK, m_frame);

		FRAMESTACK->top->frame->array[0] = pop_op();

		for (i = 1; i < (*j); i++)
			FRAMESTACK->top->frame->array[i] = array[i];

		execute(FRAMESTACK->top->frame, class);
	}
	++(FRAMESTACK->top->frame->pc);
	return 0;

}

u1 invokestatic(u1 *code) {
	u2 entry1, entry2;
	u2 n_t_index, d_index, n_index;
	u4 method_name_index = 0, descriptor_length = 0;
	u4 i = 0;
	int *j = (int*) calloc(1, sizeof(int));
	u1 *descriptor;
	u1 *method_name;
	method_info *method;
	method_frame *m_frame;
	u4 *array;


	/* calcula entrada para o pool de constantes com o nome do metodo a ser invocado */
	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 << 8;
	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 + entry2;

	n_t_index
			= MAINCLASS->constant_pool[entry1 - 1].info.Methodref.name_and_type_index; /* encontra referencia no p.c. para nome e descritor  do metodo */
	n_index
			= MAINCLASS->constant_pool[n_t_index - 1].info.NameAndType.name_index; /* encontra referencia para o nome do metodo */
	d_index
			= MAINCLASS->constant_pool[n_t_index - 1].info.NameAndType.descriptor_index; /* encontra referencia para o descritor do metodo */

	method_name = MAINCLASS->constant_pool[n_index - 1].info.Utf8.bytes;
	for (i = 0; i < MAINCLASS->methods_count; i++) {
		method_name_index = MAINCLASS->methods[i].name_index - 1;
		if (!strcmp(
				(char *) method_name,
				(char *) MAINCLASS->constant_pool[method_name_index].info.Utf8.bytes)) {
			break;
		}
	}
	/* arquivo .class nao possui metodo metodo invocado */
	if (i == MAINCLASS->methods_count) {
		printf("method not found: cannot execute\n");
		exit(0);
	} else {
		method = &(MAINCLASS->methods[i]);
	}
	m_frame = (method_frame *) new_frame(method, MAINCLASS->constant_pool, i);
	descriptor = MAINCLASS->constant_pool[d_index - 1].info.Utf8.bytes;
	descriptor_length = MAINCLASS->constant_pool[d_index - 1].info.Utf8.lenght;
	array = descriptor_parser(descriptor, descriptor_length, j);

	push_stack(FRAMESTACK, m_frame);
	for (i = 0; i < (*j); i++)
		FRAMESTACK->top->frame->array[i] = array[i];

	execute(FRAMESTACK->top->frame, MAINCLASS);

	++(FRAMESTACK->top->frame->pc);
	return 0;

}

/**/

u1 new(u1* code) {
	u1 tag;
	short int entry1, entry2;
	u2 n_t_index;
	u1 *class_name;

	entry1 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 << 8;
	entry2 = (u1) code[++(FRAMESTACK->top->frame->pc)];
	entry1 = entry1 + entry2;

	tag = MAINCLASS->constant_pool[entry1 - 1].tag;

	switch (tag) {
	/*Class*/
	case 0x07:
		n_t_index = MAINCLASS->constant_pool[entry1 - 1].info.Class.name_index;
		class_name = MAINCLASS->constant_pool[n_t_index - 1].info.Utf8.bytes;

		printf("Class name = %s \n", class_name);
		push_op(n_t_index);
		break;
		/*Array*/

		/*interface type*/
	default:
		printf("Operacao invalida, tag nao reconhecida");
	}
	printf("Opera��o new n�o implementada.\n");
	exit(1);
	++(FRAMESTACK->top->frame->pc);

	return 0;
}

u1 newarray(u1* code) {
	printf("Opera��o newarray n�o implementada.\n");
	exit(1);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 anewarray(u1* code) {
	printf("Opera��o anewarray n�o implementada.\n");
	exit(1);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 arraylength(u1* code) {
	printf("Opera��o arraylength n�o implementada.\n");
	exit(1);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 athrow(u1* code) {
	printf("Opera��o athrow n�o implementada.\n");
	exit(1);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 checkcast(u1* code) {
	printf("Opera��o checkcast n�o implementada.\n");
	exit(1);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 instanceof(u1* code) {
	printf("Opera��o instanceof n�o implementada.\n");
	exit(1);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 monitorenter(u1* code) {
	printf("Opera��o monitorenter n�o implementada.\n");
	exit(1);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 monitorexit(u1* code) {
	printf("Opera��o monitorexit n�o implementada.\n");
	exit(1);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 wide(u1* code) {
	printf("Opera��o wide n�o implementada.\n");
	exit(1);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 multianewarray(u1* code) {
	printf("Opera��o multianewarray n�o implementada.\n");
	exit(1);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 ifnull(u1* code) {
	printf("Opera��o ifnull n�o implementada.\n");
	exit(1);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 ifnonnull(u1* code) {
	printf("Opera��o ifnonnull n�o implementada.\n");
	exit(1);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 goto_w(u1* code) {
	printf("Opera��o goto_w n�o implementada.\n");
	exit(1);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u1 jsr_w(u1* code) {
	printf("Opera��o jsr_w n�o implementada.\n");
	exit(1);
	++(FRAMESTACK->top->frame->pc);
	return 0;
}

u4 *descriptor_parser(u1 *descriptor, int descriptor_length, int *j) {
	u4* array;
	u4 i = 0;
	*j = 0;
	while ((descriptor[i] != ')') && (i <= descriptor_length)) {
		if ((descriptor[i] != '(') && (descriptor[i] != 'V')) {
			(*j)++;
		}
		i++;
	}
	array = (u4*) calloc((*j), sizeof(u4));
	for (i = 0; i < (*j); i++)
		array[i] = pop_op();

	return array;
}

/* Vetor de instrucoes */
u1 (*instructions[256])(u1*);

void init_instructions(void) {

	instructions[0] = nop;
	instructions[1] = aconst_null;
	instructions[2] = iconst_m1;
	instructions[3] = iconst_0;
	instructions[4] = iconst_1;
	instructions[5] = iconst_2;
	instructions[6] = iconst_3;
	instructions[7] = iconst_4;
	instructions[8] = iconst_5;
	instructions[9] = lconst_0;
	instructions[10] = lconst_1;
	instructions[11] = fconst_0;
	instructions[12] = fconst_1;
	instructions[13] = fconst_2;
	instructions[14] = dconst_0;
	instructions[15] = dconst_1;
	instructions[16] = bipush;
	instructions[17] = sipush;
	instructions[18] = ldc;
	instructions[19] = ldc_w;
	instructions[20] = ldc2_w;
	instructions[21] = iload;
	instructions[22] = lload;
	instructions[23] = fload;
	instructions[24] = dload;
	instructions[25] = aload;
	instructions[26] = iload_0;
	instructions[27] = iload_1;
	instructions[28] = iload_2;
	instructions[29] = iload_3;
	instructions[30] = lload_0;
	instructions[31] = lload_1;
	instructions[32] = lload_2;
	instructions[33] = lload_3;
	instructions[34] = fload_0;
	instructions[35] = fload_1;
	instructions[36] = fload_2;
	instructions[37] = fload_3;
	instructions[38] = dload_0;
	instructions[39] = dload_1;
	instructions[40] = dload_2;
	instructions[41] = dload_3;
	instructions[42] = aload_0;
	instructions[43] = aload_1;
	instructions[44] = aload_2;
	instructions[45] = aload_3;
	instructions[46] = iaload;
	instructions[47] = laload;
	instructions[48] = faload;
	instructions[49] = daload;
	instructions[50] = aaload;
	instructions[51] = baload;
	instructions[52] = caload;
	instructions[53] = saload;
	instructions[54] = istore;
	instructions[55] = lstore;
	instructions[56] = fstore;
	instructions[57] = dstore;
	instructions[58] = astore;
	instructions[59] = istore_0;
	instructions[60] = istore_1;
	instructions[61] = istore_2;
	instructions[62] = istore_3;
	instructions[63] = lstore_0;
	instructions[64] = lstore_1;
	instructions[65] = lstore_2;
	instructions[66] = lstore_3;
	instructions[67] = fstore_0;
	instructions[68] = fstore_1;
	instructions[69] = fstore_2;
	instructions[70] = fstore_3;
	instructions[71] = dstore_0;
	instructions[72] = dstore_1;
	instructions[73] = dstore_2;
	instructions[74] = dstore_3;
	instructions[75] = astore_0;
	instructions[76] = astore_1;
	instructions[77] = astore_2;
	instructions[78] = astore_3;
	instructions[79] = iastore;
	instructions[80] = lastore;
	instructions[81] = fastore;
	instructions[82] = dastore;
	instructions[83] = aastore;
	instructions[84] = bastore;
	instructions[85] = castore;
	instructions[86] = sastore;
	instructions[87] = pop;
	instructions[88] = pop2;
	instructions[89] = dup;
	instructions[90] = dup_x1;
	instructions[91] = dup_x2;
	instructions[92] = dup2;
	instructions[93] = dup2_x1;
	instructions[94] = dup2_x2;
	instructions[95] = swap;
	instructions[96] = iadd;
	instructions[97] = ladd;
	instructions[98] = fadd;
	instructions[99] = dadd;
	instructions[100] = isub;
	instructions[101] = lsub;
	instructions[102] = fsub;
	instructions[103] = dsub;
	instructions[104] = imul;
	instructions[105] = lmul;
	instructions[106] = fmul;
	instructions[107] = dmul;
	instructions[108] = idiv;
	instructions[109] = _ldiv;
	instructions[110] = fdiv;
	instructions[111] = ddiv;
	instructions[112] = irem;
	instructions[113] = lrem;
	instructions[114] = frem;
	instructions[115] = _drem;
	instructions[116] = ineg;
	instructions[117] = lneg;
	instructions[118] = fneg;
	instructions[119] = dneg;
	instructions[120] = ishl;
	instructions[121] = lshl;
	instructions[122] = ishr;
	instructions[123] = lshr;
	instructions[124] = iushr;
	instructions[125] = lushr;
	instructions[126] = iand;
	instructions[127] = land;
	instructions[128] = ior;
	instructions[129] = lor;
	instructions[130] = ixor;
	instructions[131] = lxor;
	instructions[132] = iinc;
	instructions[133] = i2l;
	instructions[134] = i2f;
	instructions[135] = i2d;
	instructions[136] = l2i;
	instructions[137] = l2f;
	instructions[138] = l2d;
	instructions[139] = f2i;
	instructions[140] = f2l;
	instructions[141] = f2d;
	instructions[142] = d2i;
	instructions[143] = d2l;
	instructions[144] = d2f;
	instructions[145] = i2b;
	instructions[146] = i2c;
	instructions[147] = i2s;
	instructions[148] = lcmp;
	instructions[149] = fcmpl;
	instructions[150] = fcmpg;
	instructions[151] = dcmpl;
	instructions[152] = dcmpg;
	instructions[153] = ifeq;
	instructions[154] = ifne;
	instructions[155] = iflt;
	instructions[156] = ifge;
	instructions[157] = ifgt;
	instructions[158] = ifle;
	instructions[159] = if_icmpeq;
	instructions[160] = if_icmpne;
	instructions[161] = if_icmplt;
	instructions[162] = if_icmpge;
	instructions[163] = if_icmpgt;
	instructions[164] = if_icmple;
	instructions[165] = if_acmpeq;
	instructions[166] = if_acmpne;
	instructions[167] = _goto;
	instructions[168] = jsr;
	instructions[169] = ret;
	instructions[170] = tableswitch;
	instructions[171] = lookupswitch;
	instructions[172] = ireturn;
	instructions[173] = lreturn;
	instructions[174] = freturn;
	instructions[175] = dreturn;
	instructions[176] = areturn;
	instructions[177] = _return;
	instructions[178] = getstatic;
	instructions[179] = putstatic;
	/*
	 instructions[180] = getfield;
	 instructions[181] = putfield;
	 */
	instructions[182] = invokevirtual;
	instructions[183] = invokespecial;
	instructions[184] = invokestatic;
	/* N�o ser� implementado interface
	 instructions[185] = invokeinterface;
	 */
	/*
	 Por raz�es hit�ricas, o opcode 186 n�o � utilizado.
	 instructions[186] = xxxunusedxxx;
	 */
	instructions[187] = new;
	instructions[188] = newarray;
	instructions[189] = anewarray;
	instructions[190] = arraylength;
	instructions[191] = athrow;
	instructions[192] = checkcast;
	instructions[193] = instanceof;
	instructions[194] = monitorenter;
	instructions[195] = monitorexit;
	instructions[196] = wide;
	instructions[197] = multianewarray;
	instructions[198] = ifnull;
	instructions[199] = ifnonnull;
	instructions[200] = goto_w;
	instructions[201] = jsr_w;

	if (VERBOSE) printf("Vetor de instru��es carregado;\n");

}

void execute(method_frame *frame, class_file *class) {
	u1
			*code =
					class->methods[frame->method_index].attributes[frame->attr_code_index].info.Code.code;
	u4 i;

	int sair = 0;

	for (i = 0; !sair
			&& frame->pc
					< class->methods[frame->method_index].attributes[frame->attr_code_index].info.Code.code_lenght; i++) {
		if (VERBOSE) {
			bytecode_printer(&code[frame->pc], 1);
			/*  printf(" Opcode %d;\n", (u1) code[frame->pc]); */
		}
		sair = instructions[(u1) code[frame->pc]](code);
	}
}

void exception(int exc) {
	switch (exc) {
	case 1:
		printf("\tLong e double n�o implementado;\n");
		exit(1);
		break;
	default:
		exit(1);
	}
}
